/*
 * Copyright (c) 2022 CompanyNameMagicTag.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <Windows.h>
#include <cstdlib>
#ifdef USE_MINGW
#include <SDL2/SDL.h>
#else
#include <SDL.h>
#endif
#include <string>
#include <iostream>
#include <cstdio>
#include "common/graphic_startup.h"
#include "common/task_manager.h"
#include "common/input_device_manager.h"
#include "mouse_input.h"
#include "monitor.h"
#include "app/app.h"

using namespace std;
using namespace OHOS;

static constexpr uint32_t MIN_FONT_LENGTH = 0x380000;      // 0x380000 : MIN_FONT_LENGTH
static uint8_t g_fontBaseAddr[MIN_FONT_LENGTH];

static void InitHal()
{
    /* Add a display,use the 'monitor' driver which creates window on PC's monitor to simulate a display
     * Param1 : monitor width, Param2 : monitor height  Param3 : monitor shape
     * shape : DeviceShape::SHAPE_RECT,  DeviceShape::SHAPE_CIRCLE
     * Attention : the Param1 must equal to Param2 when shape is DeviceShape::SHAPE_CIRCLE
     */
    MonitorInit(466, 466, DeviceShape::SHAPE_CIRCLE);  // 466 x 466 : monitor size

    // Add the mouse as input device
#if USE_MOUSE
    MouseInput* mouse = new MouseInput();
    InputDeviceManager::GetInstance()->Add(mouse);
#endif
}

int main(int argc, char** argv)
{
    GraphicStartUp::Init();
    GraphicStartUp::InitFontEngine(reinterpret_cast<uintptr_t>(g_fontBaseAddr), MIN_FONT_LENGTH,
                                   "../res/", "HarmonyOS_Sans_SC_Regular.ttf");
    InitHal();
    App::GetInstance()->Init();
    RootView::GetInstance()->Invalidate();
    while (!SdlExitStatus()) {
        // Periodically call TaskHandler(). It could be done in a timer interrupt or an OS task too.
        TaskManager::GetInstance()->TaskHandler();
        Sleep(16); // 16ms : Just to let the system breathe
    }
    return 0;
}

